﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;

namespace Lightray.Hattrick
{
    public class SettingsFile
    {
        private const string FILE_NAME = "iToT.config";
        private const int MAX_FILE_SIZE = 5 * 1024; // 5K
        private const string DOCUMENT_ELEMENT = "iTrickOrTreat";

        private XmlDocument _settingsXml;
        private Dictionary<string, string> _settings;

        public SettingsFile()
        {
            loadFileCreateIfEmpty();
            readSettings();
        }

        private void readSettings()
        {
            _settings = new Dictionary<string, string>();
            foreach (XmlNode settingNode in _settingsXml.DocumentElement.ChildNodes)
                readSettingDeleteIfBad(settingNode);
        }

        private void readSettingDeleteIfBad(XmlNode settingNode)
        {
            try
            {
                _settings[settingNode.Name] = settingNode.InnerText;
            }
            catch (Exception)
            {
                // invalid or duplicate setting, delete from xml
                _settingsXml.DocumentElement.RemoveChild(settingNode);
            }
        }

        private void loadFileCreateIfEmpty()
        {
            if (!File.Exists(FILE_NAME))
                startNewFile();
            else
                loadExistingFileCreateNewIfBad();
        }

        private void loadExistingFileCreateNewIfBad()
        {
            try
            {
                if (new FileInfo(FILE_NAME).Length > MAX_FILE_SIZE)
                    throw new Exception(); // size is invalid

                _settingsXml = new XmlDocument();
                _settingsXml.Load(FILE_NAME);
                
                if (_settingsXml.DocumentElement.Name != DOCUMENT_ELEMENT)
                    throw new Exception();
            }
            catch (Exception)
            {
                File.Delete(FILE_NAME);
                startNewFile();
            }
        }

        private void startNewFile()
        {
            _settingsXml = new XmlDocument();
            _settingsXml.AppendChild(_settingsXml.CreateXmlDeclaration("1.0", "utf-8", string.Empty));
            _settingsXml.AppendChild(_settingsXml.CreateElement(DOCUMENT_ELEMENT));
            _settingsXml.Save(FILE_NAME);
        }

        public void Set(string name, string value)
        {
            _settings[name] = value;
        }

        public string Get(string name)
        {
            if (!_settings.ContainsKey(name))
                return null;                
            return _settings[name];
        }

        public string GetOrDefault(string name, string defaultValue)
        {
            _settings.TryGetValue(name, out defaultValue);
            return defaultValue;
        }

        public void Remove(string name)
        {
            if (string.IsNullOrEmpty(name))
                return;
            _settings.Remove(name);
        }

        public void Sync()
        {
            _settingsXml.DocumentElement.RemoveAll();
            foreach (var kvp in _settings)
            {
                XmlNode newNode = _settingsXml.CreateElement(kvp.Key);
                newNode.InnerText = kvp.Value;
                _settingsXml.DocumentElement.AppendChild(newNode);
            }

            _settingsXml.Save(FILE_NAME);
        }
    }
}
